/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.edu.unal.bioingenium.kbmed.knowledge.similarity;

import co.edu.unal.bioingenium.kbmed.config.Configuration;
import co.edu.unal.bioingenium.kbmed.knowledge.dao.KnowledgeSourceDAO;
import co.edu.unal.bioingenium.kbmed.knowledge.dao.KnowledgeSourceDAOFactory;
import co.edu.unal.bioingenium.kbmed.knowledge.similarity.vo.CategoryInformationContentValues;
import co.edu.unal.bioingenium.kbmed.util.io.FileManager;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Alejandro Riveros Cruz
 */
public class InformationContentService {

    /**
     * 
     */
    private static InformationContentService informationContentValuesInstance;
    /**
     * 
     */
    private Map<String, CategoryInformationContentValues> informationContentValuesMap = new HashMap<String, CategoryInformationContentValues>();

    /**
     * 
     * @return
     */
    public static InformationContentService getInstance() {
        if (informationContentValuesInstance == null) {
            informationContentValuesInstance = new InformationContentService();
        }
        return informationContentValuesInstance;
    }

    /**
     * 
     */
    private InformationContentService() {
        initCategories();
    }

    /**
     * 
     */
    private void initCategories() {
        KnowledgeSourceDAO knowledgeSourceDAO = KnowledgeSourceDAOFactory.getKnowledgeSourceDAO();
        Set<String> categories = knowledgeSourceDAO.getCategories();
        for (String category : categories) {
            getInformationContentValues(category).normalize();
        }
    }

    /**
     * 
     * @param category
     * @param conceptId
     * @return
     */
    public float getInformationContentValue(String category, String conceptId) {
        return getInformationContentValues(category).getInformationContentValue(conceptId);
    }

    private CategoryInformationContentValues getInformationContentValues(String category) {
        if (informationContentValuesMap.containsKey(category)) {
            return informationContentValuesMap.get(category);
        } else {
            CategoryInformationContentValues informationContentByCategory = loadInformationContentValues(category);
            informationContentValuesMap.put(category, informationContentByCategory);
            return informationContentByCategory;
        }
    }

    private CategoryInformationContentValues loadInformationContentValues(String category) {
        String categoryStandard = FileManager.getStandardName(category);
        BufferedReader bufferedReader = null;
        try {
            CategoryInformationContentValues informationContentCategoryValues = new CategoryInformationContentValues(category);
            bufferedReader = new BufferedReader(new FileReader(Configuration.FEATURE_DIR + File.separator + Configuration.KNOWLEDGE_SOURCE_NAME.toLowerCase() + "-" + categoryStandard + "InformationContentValues.cvs"));
            String line;
            String[] data;
            String conceptId;
            float IC;
            float maxIC = -1;
            while ((line = bufferedReader.readLine()) != null) {
                data = line.split(",");
                conceptId = data[0].intern();
                IC = Float.parseFloat(data[1]);
                informationContentCategoryValues.addInformationContentValue(conceptId, IC);
                if (IC > maxIC) {
                    maxIC = IC;
                }
            }
            bufferedReader.close();
            informationContentCategoryValues.setMaxIC(maxIC);
            Logger.getLogger(InformationContentService.class.getName()).log(Level.INFO, "Load information content values for category \"{0}\" success.", category);
            return informationContentCategoryValues;
        } catch (IOException ex) {
            Logger.getLogger(InformationContentService.class.getName()).log(Level.SEVERE, "Error loading information content values file for category " + category, ex);
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException ex) {
                Logger.getLogger(InformationContentService.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }
}
